package com.hllxd.hism.star.basic.service.collect;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hllxd.hism.star.basic.service.model.rock.YarnQuotaEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

/**
 * 从yarn jmx中获取信息转化为Map或 list
 * @author lixiyong01
 * @date 20210817
 */

public class YarnRequest {

    private static final Logger logger = LoggerFactory.getLogger(YarnRequest.class);
    /**
     * 根据URL返回List<Map<String,Object>>
     *
     * @param url  服务地址
     * @param path 服务路径
     * @param params 服务参数
     * @param tags 结果中的项
     * @return 结果列表
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String,Object>> getYarn(String url, String path, TreeMap<String, String> params,String[] tags) throws IOException {


        String res = HttpUtils.get(url + path, params);
        if(StringUtilWxf.isNotBlank(res)){
            res = res.replace("\"queueUsagePercentage\":INF","\"queueUsagePercentage\":0")
                    .replace("\"clusterUsagePercentage\":INF","\"clusterUsagePercentage\":0");
        }
        Map<String,Object> temp = JSON.parseObject(res, Map.class);
        if(temp != null && temp.size() != 0) {
            Map<String, Object> apps = (Map<String, Object>) temp.get(tags[0]);
            if (apps != null && apps.size() != 0) {
                return (List<Map<String, Object>>) apps.get(tags[1]);
            }
        }
        return ListUtils.newArrayList();
    }


    /**
     * 根据URL返回List<Map<String,Object>>
     *
     * @param url 服务路径
     * @param path 执行路径
     * @param params 执行参数
     * @param tag 结果中的项标识
     * @return 返回解析后的结果
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String,Object>> getYarnOne(String url, String path, TreeMap<String, String> params,String tag) throws IOException {
        String res = HttpUtils.get(url + path, params);
        if(StringUtilWxf.isNotBlank(res)){
            res = res.replace("\"queueUsagePercentage\":INF","\"queueUsagePercentage\":0")
                    .replace("\"clusterUsagePercentage\":INF","\"clusterUsagePercentage\":0");
        }
        Map<String,Object> temp = JSON.parseObject(res, Map.class);
        if(temp != null && temp.size() != 0) {
            List<Map<String, Object>> listMap = new ArrayList<>();
            Map<String, Object> item = (Map<String, Object>) temp.get(tag);
            if (item != null && item.size() != 0) {
                listMap.add(item);
                return listMap;
            }
        }
        return ListUtils.newArrayList();
    }

    /**
     *
     * @param url 服务路径
     * @param path 执行路径
     * @return 获取指定队列使用
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static List<YarnQuotaEntity> getYarnScheduler(String url, String path) throws IOException {
        String res = HttpUtils.get(url + path, null);
        JSONObject obj = JSON.parseObject(res);
        JSONObject scheduler = obj.getJSONObject("scheduler");
        JSONObject schedulerInfo = scheduler.getJSONObject("schedulerInfo");
        JSONObject rootQueue = schedulerInfo.getJSONObject("rootQueue");
        JSONObject childQueues = rootQueue.getJSONObject("childQueues");
        JSONArray queue = childQueues.getJSONArray("queue");
        List<YarnQuotaEntity> quotas = new ArrayList<>();
        for(int i=0;i<queue.size();i++) {
            JSONObject item = queue.getJSONObject(i);
            List<YarnQuotaEntity> quotas2 = loadChildQueues(item);
            if(quotas2==null) {
                continue;
            }
            quotas.addAll(quotas2);
        }
        return quotas;
    }
    private static List<YarnQuotaEntity> loadChildQueues(JSONObject rootQueue) {
        JSONObject childQueues = rootQueue.getJSONObject("childQueues");
        if(childQueues==null) {
            return null;
        }
        List<YarnQuotaEntity> quotas = new ArrayList<>();
        JSONArray queue = childQueues.getJSONArray("queue");
        for(int i=0;i<queue.size();i++) {
            JSONObject item = queue.getJSONObject(i);
            YarnQuotaEntity quota = parseQueue(item);
            if(quota==null) {
                continue;
            }
            quotas.add(quota);
        }
        return quotas;
    }

    static String SUPIN_QUEUE = "root.offline.hdp_lbg_supin";
    static String ZHAOPINPIN_QUEUE = "root.offline.hdp_lbg_zhaopin";
    private static YarnQuotaEntity parseQueue(JSONObject item) {
        String queueName = item.getString("queueName");
        Long minMemory = item.getJSONObject("minResources").getLong("memory");
        Long minVCores = item.getJSONObject("minResources").getLong("vCores");
        Long maxMemory = item.getJSONObject("maxResources").getLong("memory");
        Long maxVCores = item.getJSONObject("maxResources").getLong("vCores");
        Long usedMemory = item.getJSONObject("usedResources").getLong("memory");
        Long usedVCores = item.getJSONObject("usedResources").getLong("vCores");
        if(queueName.equals(SUPIN_QUEUE) || queueName.equals(ZHAOPINPIN_QUEUE)) {
            logger.info("queueName:{}, memory:{}/{},{}, vCores: {}/{},{}.", queueName,
                    usedMemory, minMemory, maxMemory,
                    usedVCores, minVCores, maxVCores);
            return YarnQuotaEntity.build(queueName,usedVCores, minVCores, maxVCores, usedMemory, minMemory, maxMemory);
        }
        return null;
    }
    /**
     * @param url
     * @param ziurl  url + ziurl凭借完整URL
     * @param paramUrl url参数
     * @param jibie 返回数据时有层级关系,真正的数据在某一层中，需要指定层级关系
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String,Object>> getAppNumUrl(String url,String ziurl, TreeMap<String, String> paramUrl,String[] jibie) throws IOException {

        String res = HttpUtils.get(url + ziurl, paramUrl);
        if(StringUtilWxf.isNotBlank(res)){
            res = res.replace("\"queueUsagePercentage\":INF","\"queueUsagePercentage\":0")
                    .replace("\"clusterUsagePercentage\":INF","\"clusterUsagePercentage\":0");
        }

        Map<String,Object> temp = JSON.parseObject(res, Map.class);

        if(temp != null && temp.size() != 0) {

            Map<String, Object> apps = (Map<String, Object>) temp.get(jibie[0]);
            if (apps != null && apps.size() != 0) {
                return (List<Map<String, Object>>) apps.get(jibie[1]);
            }
        }

        return ListUtils.newArrayList();
    }

    /**
     * 根据URL返回Map<String,Object>
     * @param url
     * @param ziurl
     * @param paramUrl
     * @param jibie
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public static Map<String,Object> getYarn(String url, String ziurl, TreeMap<String, String> paramUrl,String jibie) throws IOException {


        String res = HttpUtils.get(url + ziurl, paramUrl);

        if(StringUtilWxf.isNotBlank(res)){
            res = res.replace("\"queueUsagePercentage\":INF","\"queueUsagePercentage\":0")
                    .replace("\"clusterUsagePercentage\":INF","\"clusterUsagePercentage\":0");
        }

        Map<String,Object> temp = JSON.parseObject(res, Map.class);

        if(temp != null && temp.size() != 0) {
            return (Map<String, Object>) temp.get(jibie);
        }
        return new HashMap<>(1);
    }

    @SuppressWarnings("unchecked")
    public static Map<String,Object> getJmxInfo(String url, String ziurl, TreeMap<String, String> paramUrl,String jibie) throws IOException {


        String res = HttpUtils.get(url + ziurl, paramUrl);

        if(StringUtilWxf.isNotBlank(res)){
            res = res.replace("\"queueUsagePercentage\":INF","\"queueUsagePercentage\":0")
                    .replace("\"clusterUsagePercentage\":INF","\"clusterUsagePercentage\":0");
        }


        Map<String,Object> temp = JSON.parseObject(res, Map.class);

        if(temp != null && temp.size() != 0) {
            //Map<String, Object> apps = (Map<String, Object>)
            List list = (List) temp.get(jibie);
            return (LinkedHashMap) list.get(0);
        }
        return new HashMap<>(0);
    }

}
